package rifa.persistence.facade;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;

import rifa.entidade.Entidade;
import rifa.entidade.Estado;

public class AppManager<E extends Entidade> {

	private static EntityManagerFactory factory;

	static {
		factory = Persistence.createEntityManagerFactory("rifa");
	}

	public AppManager() {
	}

	public void insereObjeto(Entidade entidade) {
		EntityManager manager;
		manager = factory.createEntityManager();
		try {
			EntityTransaction transaction = manager.getTransaction();
			transaction.begin();
			manager.persist(entidade);
			transaction.commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (manager != null && manager.isOpen()) {
				manager.close();
			}
		}
	}

	public void updateObjeto(Entidade entidade) {
		EntityManager manager;
		manager = factory.createEntityManager();
		EntityTransaction transaction = manager.getTransaction();
		try {

			transaction = manager.getTransaction();
			transaction.begin();
			manager.merge(entidade);
			transaction.commit();

		} catch (Exception e) {
			if (transaction != null && transaction.isActive()) {
				transaction.rollback();
			}
			e.printStackTrace();
		} finally {
			if (manager != null && manager.isOpen()) {
				manager.close();
			}
		}
	}

	public void deleteObjeto(Entidade entidade) {
		EntityTransaction transaction = null;
		EntityManager manager;
		manager = factory.createEntityManager();
		try {
			transaction = manager.getTransaction();
			transaction.begin();
			manager.remove(manager.merge(entidade));
			transaction.commit();
		} catch (Exception e) {
			if (transaction != null && transaction.isActive()) {
				transaction.rollback();
			}
			e.printStackTrace();
		} finally {
			if (manager != null && manager.isOpen()) {
				manager.close();
			}
		}
	}

	public Entidade getById(Long codigo, Class<E> classe) {
		Entidade entidade = null;
		EntityManager manager;
		manager = factory.createEntityManager();
		try {
			entidade = manager.find(classe, codigo);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (manager != null && manager.isOpen()) {
				manager.close();
			}
		}
		return entidade;
	}

	public List<? extends Entidade> findAll(Class<? extends Entidade> classe) {
		List<? extends Entidade> result = null;
		EntityManager manager;
		manager = factory.createEntityManager();
		try {
			String jpql = "select e from " + classe.getSimpleName() + " e";
			Query consulta = manager.createQuery(jpql);

			result = consulta.getResultList();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (manager != null && manager.isOpen()) {
				manager.close();
			}
		}
		return result;
	}

	public List<? extends Entidade> getObjectByAtribute(String atribute, Object value,
			Class<? extends Entidade> classe) {
		List<? extends Entidade> result = null;
		EntityManager manager;
		manager = factory.createEntityManager();
		try{
		String jpql = "select e from " + classe.getSimpleName() + " e where e."
				+ atribute + "= ?";
		Query query = manager.createQuery(jpql);
		query.setParameter(1, value);
		result = query.getResultList();}
		catch(Exception e){
			e.printStackTrace();
		}
		finally{
			if (manager != null && manager.isOpen()) {
				closeManager(manager);
			}
		}
		return result;
		
	}
	
	public void closeManager(EntityManager manager){
		manager.close();
	}
}
